package com.suzhe.ymall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.suzhe.ymall.common.exception.YMallException;
import com.suzhe.ymall.common.utils.RedisKeys;
import com.suzhe.ymall.common.utils.RedisTemplateUtils;
import com.suzhe.ymall.common.utils.YMJsonUtils;
import com.suzhe.ymall.product.convert.ProductConvert;
import com.suzhe.ymall.product.mapper.SpuMapper;
import com.suzhe.ymall.product.param.SpuAttrParam;
import com.suzhe.ymall.product.param.SpuSaleAttrOptionParam;
import com.suzhe.ymall.product.param.SpuSaleAttrParam;
import com.suzhe.ymall.product.param.SpuUpdateParam;
import com.suzhe.ymall.product.pojo.*;
import com.suzhe.ymall.product.service.*;
import com.suzhe.ymall.product.vo.SpuVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * spu表 服务实现类
 * </p>
 *
 * @author suzhe
 * @since 2019-07-06
 */
@Service
@Slf4j
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements ISpuService {
    @Autowired
    ISkuService iSkuService;

    @Autowired
    ISpuDetailService iSpuDetailService;

    @Autowired
    IStockService iStockService;

    @Autowired
    ICategoryService iCategoryService;

    @Autowired
    IBrandService iBrandService;



    @Override
    @Transactional
    public boolean saveSpu(Spu spu) {
        List<String> showImgList = spu.getShowImgList();

        Collection<Category> categories = iCategoryService.listByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));
        String categoryName = categories.stream().map(item -> item.getName()).collect(Collectors.joining("/"));
        spu.setCname(categoryName);
        spu.setShowImg(YMJsonUtils.toJson(showImgList));
        save(spu);
        List<Sku> skus = spu.getSkus();

        List<SpuSaleAttrParam> saleAttr = spu.getSaleAttr();
        //根据销售属性生成id - imgUrl的映射，sku里的imgUrl设置是会用到
        Map<String, String> optionMap = getOptionMap(saleAttr);

        skus.forEach(item -> {
            item.setSpuId(spu.getId());
            LinkedHashMap<String, String> attrMap = item.getAttrMap();
            String title = "";
            for (String value : attrMap.values()) {
                title = title + value + " ";
            }
            String saleAttrId = item.getAttrKey().split("_")[0];
            item.setImgUrl(optionMap.get(saleAttrId));
            item.setTitle(title);
            item.setAttr(YMJsonUtils.toJson(attrMap));
            iSkuService.save(item);
            Stock stock = new Stock();
            stock.setSkuId(item.getId());
            stock.setStock(item.getStock());
            iStockService.save(stock);
        });
        List<SpuAttrParam> attr = spu.getAttr();

        SpuDetail spuDetail = new SpuDetail();
        spuDetail.setSpuId(spu.getId());
        spuDetail.setAttr(YMJsonUtils.toJson(attr));
        spuDetail.setSaleAttr(YMJsonUtils.toJson(saleAttr));
        spuDetail.setDescription(spu.getDescription());
        spuDetail.setPackingList(spu.getPackingList());
        iSpuDetailService.save(spuDetail);

        return true;
    }

    private Map<String, String> getOptionMap(List<SpuSaleAttrParam> saleAttr) {
        List<SpuSaleAttrOptionParam> firstOptions = saleAttr.get(0).getOptions();
        return firstOptions.stream()//
                .collect(Collectors.toMap(item -> String.valueOf(item.getId()), item -> item.getImgUrl()));
    }

    @Transactional
    @Override
    public boolean updateSpu(SpuUpdateParam spuUpdateParam) {
        Spu oldSpu = getById(spuUpdateParam.getId());
        if (oldSpu == null){
            throw new YMallException("不存在该商品");
        }
        Spu spu = ProductConvert.MAPPER.updateParamToSpu(spuUpdateParam);
        updateById(spu);

        SpuDetail spuDetail = new SpuDetail();
        spuDetail.setSpuId(spuUpdateParam.getId());
        spuDetail.setSaleAttr(YMJsonUtils.toJson(spu.getSaleAttr()));
        spuDetail.setDescription(spuUpdateParam.getDescription());
        spuDetail.setPackingList(spuUpdateParam.getPackingList());
        spuDetail.setAttr(YMJsonUtils.toJson(spuUpdateParam.getAttr()));
        iSpuDetailService.updateById(spuDetail);

        ArrayList<Stock> updateSkuStock = new ArrayList<>();
        ArrayList<Sku> updateSkus = new ArrayList<>();

        List<SpuSaleAttrParam> saleAttr = spu.getSaleAttr();
        //根据销售属性生成id - imgUrl的映射，sku里的imgUrl设置是会用到
        Map<String, String> optionMap = getOptionMap(saleAttr);
        spuUpdateParam.getSkus().forEach(item -> {
            Sku sku = new Sku();
            sku.setId(item.getId());
            sku.setPrice(item.getPrice());
            sku.setEnable(item.getEnable());
            sku.setSkuCode(item.getSkuCode());
            String saleAttrId = item.getAttrKey().split("_")[0];
            item.setImgUrl(optionMap.get(saleAttrId));
            updateSkus.add(sku);
            Stock stock = new Stock();
            stock.setStock(item.getStock());
            stock.setSkuId(item.getId());
            updateSkuStock.add(stock);
        });
        iSkuService.updateBatchById(updateSkus);
        iStockService.updateBatchById(updateSkuStock);

        return true;
    }

    @Override
    public SpuVo getSpuVo(Integer id) {
        Spu spu = getById(id);
        SpuVo spuVo = ProductConvert.MAPPER.spuToSpuVo(spu);
        SpuDetail spuDetial = iSpuDetailService.getById(id);
        spuVo.setSaleAttr(YMJsonUtils.toList(spuDetial.getSaleAttr(), SpuSaleAttrParam.class));
        spuVo.setAttr(YMJsonUtils.toList(spuDetial.getAttr(), SpuAttrParam.class));
        spuVo.setShowImgList(YMJsonUtils.toList(spu.getShowImg(), String.class));
        spuVo.setDescription(spuDetial.getDescription());
        spuVo.setPackingList(spuDetial.getPackingList());
        Brand brand = iBrandService.getById(spu.getBrandId());
        spuVo.setBrandName(brand.getName());
        List<Sku> skus = iSkuService.list(new QueryWrapper<Sku>().eq("spu_id", id));

        List<Integer> skuIds = skus.stream().map(item -> item.getId()).collect(Collectors.toList());

        List<Stock> stocks = iStockService.list(new QueryWrapper<Stock>().in("sku_id", skuIds));

        Map<Integer, Stock> stockMap = stocks.stream().collect(Collectors.toMap(Stock::getSkuId, item -> item));
        skus.forEach(item -> {
            item.setAttrMap(YMJsonUtils.toBean(item.getAttr(),LinkedHashMap.class));
            Stock stock = stockMap.get(item.getId());
            item.setStock(stock.getStock());
        });

        spuVo.setSkus(skus);
        return spuVo;
    }

}
